package bad;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Any {

    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue<Integer> integerMyBlockingQueue = new MyBlockingQueue<>(5);
        new Thread(()->{
            int i = 0;
            int t=0;
            while (true){
                i++;
                t= i<10? 1000 :2000;
                SomeTopic.debug(String.format("第%d个商品将要被生产出来", i));
                try {
                    Thread.sleep(t);
                    int p = i*10;
                    integerMyBlockingQueue.put(p);
                    SomeTopic.debug(String.format("第%d个商品已经被生产出来,它是%d", i,p));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"producer").start();
        new Thread(()->{
            int i = 0;
            int t=0;
            while (true){
                i++;
                t= i<10? 3000 :1000;
                SomeTopic.debug(String.format("第%d个商品将要被消费出来", i));
                try {
                    Thread.sleep(t);
                    int p = integerMyBlockingQueue.take();
                    SomeTopic.debug(String.format("第%d个商品已经被消费出来,它是%d", i,p));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"consumer").start();
        while (true){
            Thread.sleep(1000);
            SomeTopic.debug(integerMyBlockingQueue.inner);
        }

    }
    static class MyBlockingQueue<E>{
        private LinkedList<E> inner;
        private int size;

        private ReentrantLock id = new ReentrantLock();
        private Condition gong_an_ju= id.newCondition();
        private Condition jian_cha_yuan= id.newCondition();

        public MyBlockingQueue(int size) {
            this.inner = new LinkedList<>();
            this.size=size;
        }


        public void put(E e) throws InterruptedException {
            id.lock();
            try {
                while (inner.size() == size) {
//                wait
                    jian_cha_yuan.await();
                }
                inner.addLast(e);
//            notice innersize=1|2|3...
                gong_an_ju.signal();
            }finally {

                id.unlock();
            }
        }


        public E take() throws InterruptedException {
            E e ;
            id.lock();
            try {
                while (inner.size() == 0) {
//                wait
                    gong_an_ju.await();
                }
                e = inner.removeFirst();

//            notice innersize = 9|8|7...
                jian_cha_yuan.signal();
                return e;
            }finally {
                id.unlock();
            }


        }


    }
}
